#include "darkmagic/IEntityComponent.hpp"

#include "mylog.hpp"

#include "ncurses.h"

#include <string>

namespace darkmagic {
	IEntityComponent::IEntityComponent() {}
	IEntityComponent::~IEntityComponent() {}

	bool IEntityComponent::mvUP(int dist) {
		for( int i = 0; i <= (_s.length() - 1); i++ ) { mvwaddstr(this->_win, y, x, _e.c_str()); }
		y -= dist;
		this->checkBounds();
		return true;
	}
	bool IEntityComponent::mvDOWN(int dist) {
		for( int i = 0; i <= (_s.length() - 1); i++ ) { mvwaddstr(this->_win, y, x, _e.c_str()); }
		y += dist;
		this->checkBounds();
		return true;
	}
	bool IEntityComponent::mvLEFT(int dist) {
		for( int i = 0; i <= (_s.length() - 1); i++ ) {
			mvwaddstr(this->_win, y, x, _e.c_str());
			x -= dist;
			this->checkBounds();
		}
		return true;
	}
	bool IEntityComponent::mvRIGHT(int dist) {
		for( int i = 0; i <= (_s.length() - 1); i++ ) {
			mvwaddstr(this->_win, y, x, _e.c_str());
			x += dist;
			this->checkBounds();
		}
		return true;
	}

	bool IEntityComponent::mv(direction dir, int dist) {
		switch( dir ) {
			case direction::up:
				this->mvUP(dist);
			case direction::down:
				this->mvDOWN(dist);
			case direction::left:
				this->mvLEFT(dist);
			case direction::right:
				this->mvRIGHT(dist);
			default:
				mylog::warning("Unknown direction: " + std::to_string(dir));
				return false;
		}
		return true;
	}
	bool IEntityComponent::mvTo(uint x, uint y) {
		this->x = x;
		this->y = y;
		this->checkBounds();
		mvwaddstr(this->_win, y, x, _s.c_str());
		return true;
	}

	int IEntityComponent::getX() {
		return x;
	}
	int IEntityComponent::getY() {
		return y;
	}

	void IEntityComponent::draw() {
		mvwaddstr(this->_win, this->y, this->x, this->_s.c_str());
		// wrefresh(this->_win);
	}
	void IEntityComponent::checkBounds() {
		if( y < 1 ) {
			mylog::note("Provided value for entity <insert id>\'s Y was less then 1, correcting...");
			y = 1;
		} else if( y > getmaxy(this->_win) - 2 ) {
			mylog::note("Provided value for entity <insert id>\'s Y was greater then window size, correcting...");
			y = getmaxy(this->_win) - 2;
		}

		if( x < 1 ) {
			mylog::note("Provided value for entity <insert id>\'s X was less then 1, correcting...");
			x = 1;
		} else if( x > (getmaxx(this->_win) - 1) - _s.length() ) {
			mylog::note("Provided value for entity <insert id>\'s Y was greater then window size, correcting...");
			x = (getmaxx(this->_win) - 1) - _s.length();
		}
	}

	bool IEntityComponent::isTouching(IEntityComponent& other) {
		bool xMatch = (other.getX() == this->x);
		bool yMatch = (other.getY() == this->y);
		if( xMatch && yMatch ) { return true; }
		return false;
	}

	void IEntityComponent::addEvent(WINDOW** myWin) {
		copywin(*myWin, this->_win, 0, 0, 0, 0, getmaxy(this->_win), getmaxx(this->_win), overlay(*myWin, this->_win));
	}

} // namespace darkmagic
